home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 17
/
CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso
/
CUCD
/
Programming
/
DiceSource
/
master
/
Examples
/
Visual
/
VMake
/
process.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-01
|
12KB
|
332 lines
#include "vmake.h"
#include <dos/dostags.h>
Prototype int InitSession(void);
Prototype void TermSession(void);
Prototype void PostLog(char *msg);
Prototype int IssueCommand(char *cmd);
Prototype int setup_cli(void);
/******************************************************************************/
static APTR pr_ConsoleTask; /* Console handler process for current window */
static BPTR Outfh; /* Filehandle for session output */
static BPTR Sesfh; /* Filehandle for session Input/Output */
static LONG cli_Interactive; /* Boolean; True if prompts required */
static LONG cli_Background; /* Boolean; True if CLI created by RUN */
static struct Process *SesProcess;
/******************************************************************************/
/***********************************************************************************
* Procedure: InitSession
* Synopsis: rc = InitSession()FreeVec(vec);
* Purpose: This code returns a vector to storage
***********************************************************************************/
int InitSession()
{
struct FileHandle *handle;
struct CommandLineInterface *cli;
if (!Sesfh)
{
char cbuf[256];
SesProcess = (struct Process *)FindTask(0);
cli = BADDR(SesProcess->pr_CLI);
/* Save the current console and background status information */
pr_ConsoleTask = SesProcess->pr_ConsoleTask;
cli_Interactive = cli->cli_Interactive;
cli_Background = cli->cli_Background;
/* Open up our console to do the work */
if (!build_command(cbuf, 255, global.text[CONFIG_CONSOLE], 0))
/* JAT's usual inverted logic... */
Sesfh = Open(cbuf, MODE_OLDFILE);
else
/* error message (since we don't knowwhat build_command() produced */
strcpy(cbuf, global.text[CONFIG_CONSOLE]);
if (Sesfh == NULL)
{
Sesfh = Open("Con:0/0/320/100/Vmake_Default/Auto", MODE_OLDFILE);
if (Sesfh == NULL)
/* nowhere to put an error message, give up */
return(1);
else
{
char buf[256];
sprintf(buf, "Bad Console \"%s\" from file: %s\n",
cbuf, Sym_Lookup(SYM_CONFIG));
PostLog(buf);
}
}
handle = (struct FileHandle *)(Sesfh << 2);
SesProcess->pr_CIS = SesProcess->pr_COS = Sesfh;
SesProcess->pr_ConsoleTask = (APTR)handle->fh_Type;
if (DOSBase->dl_lib.lib_Version >= 36)
Outfh = Open("*", MODE_NEWFILE);
cli->cli_Interactive = DOSTRUE;
cli->cli_Background = DOSFALSE;
atexit(TermSession);
}
return(0);
}
/***********************************************************************************
* Procedure: TermSession
* Synopsis: (void)TermSession();
* Purpose: Terminate usage of the Session
***********************************************************************************/
void TermSession()
{
struct CommandLineInterface *cli;
if (Sesfh)
{
cli = BADDR(SesProcess->pr_CLI);
Close(Sesfh);
if (Outfh) Close(Outfh);
Sesfh = Outfh = 0;
SesProcess->pr_ConsoleTask = pr_ConsoleTask;
cli->cli_Interactive = cli_Interactive;
cli->cli_Background = cli_Background;
}
}
/***********************************************************************************
* Procedure: PostLog
* Synopsis: (void)PostLog(message);
* Purpose: Output a message to the session log
***********************************************************************************/
void PostLog(char *msg)
{
if (!InitSession())
{
Write(Sesfh, msg, strlen(msg));
Write(Sesfh, "\n", 1);
}
}
/***********************************************************************************
* Procedure: IssueCommand
* Synopsis: rc = IssueCommand(cmd);
* Purpose: Execute a given command with the current console
***********************************************************************************/
int IssueCommand(char *cmd)
{
int rc;
struct TagItem taglist[4];
rc = InitSession();
if (!rc)
{
if (Outfh)
{
taglist[0].ti_Tag = SYS_UserShell;
taglist[0].ti_Data = 1;
taglist[1].ti_Tag = SYS_Input;
taglist[1].ti_Data = (ULONG)Sesfh;
taglist[2].ti_Tag = SYS_Output;
taglist[2].ti_Data = (ULONG)Outfh;
taglist[3].ti_Tag = TAG_DONE;
rc = SystemTagList(cmd, taglist);
}
else
{
rc = Execute(cmd, 0L, Sesfh);
}
}
return(rc);
}
/***********************************************************************************
* Procedure: Alloc_Vec
* Synopsis: newvec = Alloc_Vec(size);
* Purpose: This code allocates a DOS vector
* Note: This storage is NOT automatically freed by the compiler library.
***********************************************************************************/
static BPTR Alloc_Vec(int size)
{
long *new;
size += 4;
/* Based on the given size, allocate the right amount of memory */
new = (long *)AllocMem(size, MEMF_PUBLIC | MEMF_CLEAR);
if (new != NULL)
{
/* Remember to point one past the length longword */
*new++ = size;
}
else
{
request(1, TEXT_NOMEM, NULL, NULL);
}
return(MKBADDR(new));
}
/***********************************************************************************
* Procedure: Free_Vec
* Synopsis: (void)FreeVec(vec);
* Purpose: This code returns a vector to storage
***********************************************************************************/
static void Free_Vec(BPTR orig)
{
long *in;
in = (long *)BADDR(orig);
in--; /* Back up to the size information for the original allocation */
/* Based on the given size, allocate the right amount of memory */
FreeMem(in, *in);
}
/* This structure maps a DOS Path entry. This is not really documented in any */
/* of the DOS include files but is generally understood */
/* Note that it must allocated as a dos vector (length byte in front of it) */
struct PathEnt {
BPTR nextent;
BPTR lock;
};
/***********************************************************************************
* Procedure: freecli
* Synopsis: (void)freecli();
* Purpose: This code frees up any CLI allocated structures.
* Note: This routine is only called as an autoexit routine when setup_cli
* has done some work. Otherwise we assume that no special work had to
* be done to make things happen.
***********************************************************************************/
static void freecli()
{
struct CommandLineInterface *cli;
BPTR oldent;
cli = BADDR(SesProcess->pr_CLI);
if (!cli) return;
/* We only need to free the 4 vectors we created and all of the */
/* locks on the the path list. */
Free_Vec(cli->cli_SetName);
Free_Vec(cli->cli_CommandName);
Free_Vec(cli->cli_Prompt);
Free_Vec(cli->cli_CommandFile);
while((oldent = cli->cli_CommandDir) != 0)
{
struct PathEnt *pathent;
/* First we need to remove us from the path list */
pathent = BADDR(oldent);
cli->cli_CommandDir = pathent->nextent;
UnLock(pathent->lock); /* Free the lock at this entry */
Free_Vec(oldent); /* Free the storage for the path node */
}
SesProcess->pr_CLI = 0;
}
/***********************************************************************************
* Procedure: setup_cli()
* Synopsis: (void)setup_cli();
* Purpose: This code sets up a fake CLI structure by copying the appropriate
* information from workbench. It will prepare for that to be
* automatically be freed on program termination through freecli.
***********************************************************************************/
int setup_cli()
{
struct CommandLineInterface *cli, *wbcli;
struct Process *wbproc;
struct PathEnt *pathent, *wbent;
SesProcess = (struct Process *)FindTask(0);
/* Allocate a CLI structure if we need one */
if (SesProcess->pr_CLI) return;
cli = get_mem(sizeof(struct CommandLineInterface));
if (cli == NULL) return(1);
atexit(freecli);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Next we need to go through and copy the workbench path over to */
/* Our process. The only things we need to duplicate are: */
/* */
/* We need to copy over the BPTR link list for this one. */
/* pr_CLI->cli_CommandDir Head of the path locklist */
/* */
/* These are buffers which we need to allocate space for and clone */
/* pr_CLI->cli_SetName Name of current directory */
/* pr_CLI->cli_CommandName Name of current command */
/* pr_CLI->cli_Prompt Current prompt (set by PROMPT) */
/* pr_CLI->cli_CommandFile Name of EXECUTE command file */
/* */
/* These fields are just copied over verbatim */
/* pr_CLI->cli_FailLevel Fail level (set by FAILAT) */
/* pr_CLI->cli_Interactive Boolean; True if prompts required */
/* pr_CLI->cli_Background Boolean; True if CLI created by RUN */
/* pr_CLI->cli_DefaultStack Stack size to be obtained in long words */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
SesProcess->pr_CLI = MKBADDR(cli);
/* Now we need to find the workbench CLI */
if ( ( (wbproc = (struct Process *)FindTask("Workbench")) == NULL) &&
( (wbproc = (struct Process *)FindTask("Fastbench")) == NULL) )
{
/* For some reason workbench and FastBench are not in the system */
/* We need to punt and not let them really do any work */
return(2);
}
wbcli = BADDR(wbproc->pr_CLI);
/* Say what?? We have a workbench but it doesn't have a CLI??? */
if (wbcli == NULL) return(3);
/* Do all of the staight copies from the Workbench CLI */
cli->cli_FailLevel = 20;
cli->cli_Interactive = DOSFALSE;
cli->cli_Background = DOSFALSE;
cli->cli_DefaultStack = 2048; /* Longwords */
/* Next we get all of the cloned vector buffers */
cli->cli_SetName = Alloc_Vec( 80); /* These numbers are truely magic */
cli->cli_CommandName = Alloc_Vec(104); /* and CAN NOT be changed for true */
cli->cli_Prompt = Alloc_Vec( 60); /* compatibility with 1.3. */
cli->cli_CommandFile = Alloc_Vec( 40); /* Don't even try to change them */
/* Lastly we need to copy over all of the paths from workbench */
if (wbcli->cli_CommandDir)
{
/* Start out the process by copying over the first vector */
cli->cli_CommandDir = Alloc_Vec(8);
wbent = BADDR(wbcli->cli_CommandDir);
pathent = BADDR(cli->cli_CommandDir);
/* Now loop through copying over the vector and then replacing everything */
/* in place. This looks a little strange because we are actually counting */
/* on creating a structure with a pointer to the other linked list, but */
while(wbent->nextent)
{
pathent->nextent = Alloc_Vec(8);
pathent->lock = DupLock(wbent->lock);
if (!pathent->lock)
{
pathent->nextent = 0; /* Make sure we terminate the list here */
return(4);
}
wbent = BADDR(wbent->nextent);
pathent = BADDR(pathent->nextent);
}
pathent->lock = DupLock(wbent->lock);
if (!pathent->lock) return(5);
}
}